﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WatiN.Core;
using WatiN.Core.DialogHandlers;


namespace AutoCokeZeroTest
{
    public enum BrowserType
    {
        InternetExplorer,
        Firefox
    }
    
    public class BrowserDriver
    {
        public static Browser ActiveBrowser = null;
        private IE attachedBrowser = null;
        private PrintDialogHandler printDialogHandler = null;

        public void Invoke()
        {
            Invoke(BrowserType.InternetExplorer);
        }

        public IE AttachedBrowser
        {
            get { return attachedBrowser; }
        }

        public void Invoke(BrowserType browserType)
        {
            // Launch browser according to the set browser type
            switch (browserType)
            {
                case BrowserType.InternetExplorer:
                    if (ActiveBrowser == null)
                    {
                        Console.WriteLine("Launching new IE browser");
                        ActiveBrowser = new IE(true);
                        
                        
                        ClearIECache();
                    }
                    break;

                case BrowserType.Firefox:
                    if (ActiveBrowser == null)
                    {
                        Console.WriteLine("Launching new Firefox browser");
                        ActiveBrowser = new FireFox();
                    }
                    break;
            }
        }

        public void AttachTo(string url)
        {
            Console.WriteLine("Attaching to url" + url);
            attachedBrowser = Browser.AttachTo<IE>(Find.ByUrl(url));
        }

        /// <summary>
        /// Attach to the latest opened IE
        /// </summary>
        public void AttachToLatestOpenedIE()
        {
            Console.WriteLine("Attaching to the latest opened IE browser");
            var ieCol = IE.InternetExplorersNoWait();
            int count = ieCol.Count;
            if (count > 0)
            {
                attachedBrowser = ieCol[0];
                attachedBrowser.WaitForComplete();
                Console.WriteLine("Attched and page loading complete");
            }
        }

        public void NavigateTo(string url)
        {
            try
            {
                Console.WriteLine("Navigating to url:");
                Console.WriteLine(url);
                ActiveBrowser.GoTo(url);
            }
            catch (Exception ex)
            {
                Console.WriteLine("The following error occurs when loading the url but was ignored");
                Console.WriteLine(ex.Message);
            }
        }

        public void NavigateTo(IE ie, string url)
        {
            try
            {
                Console.WriteLine("Navigating to url:");
                Console.WriteLine(url);
                ie.GoTo(url);
            }
            catch (Exception ex)
            {
                Console.WriteLine("The following error occurs when loading the url but was ignored");
                Console.WriteLine(ex.Message);
            }
        }

        public void NavigateTo(string url, int timeout)
        {
            try
            {
                Settings.WaitForCompleteTimeOut = timeout;
                Console.WriteLine("Navigating to url:");
                Console.WriteLine(url);
                ActiveBrowser.GoTo(url);
            }
            catch (Exception ex)
            {
                //use try catch to 'fix' the WatiN internet explorer busy bug
                Console.WriteLine("The following error occurs when loading the url but was ignored");
                Console.WriteLine(ex.Message);
            }
            finally
            {
                Settings.WaitForCompleteTimeOut = 30;
            }
        }

        public void NavigateToNoWait(string url)
        {
            Console.WriteLine("Navigating to the url without waiting for IE complete:");
            Console.WriteLine(url);
            ActiveBrowser.GoToNoWait(url);
        }

        public void NavigateTo(string url, bool IsRefreshPageIf404, int numOfRefreshes)
        {

            NavigateTo(url);

            if (IsRefreshPageIf404 && ActiveBrowser.Title.Contains("404") || ActiveBrowser.Title.ToLower().Contains("page not found"))
            {
                int bail = 0;
                while (bail < numOfRefreshes)
                {

                    if (bail == numOfRefreshes)
                    {
                        return;
                    }
                    NavigateTo(url);
                    
                    bail++;

                }
            }
        }

        public void ShowDefaultWindow()
        {
            ActiveBrowser.ShowWindow(WatiN.Core.Native.Windows.NativeMethods.WindowShowStyle.ShowDefault);
        }

        public void RefreshDomTree()
        {
            //Manager.Current.ActiveBrowser.RefreshDomTree();
            try
            {
                Console.WriteLine("Attaching the ActiveBrowser to itself to refresh the dom tree");
                ActiveBrowser = IE.AttachTo<IE>(Find.ByUrl(ActiveBrowser.Url));
            }
            catch (Exception)
            {
                //help try fix the watiN timeout issue sometimes when doing the attach
                ActiveBrowser = IE.AttachToNoWait<IE>(Find.ByUrl(ActiveBrowser.Url));
            }
        }

        public void ClearIECookie()
        {

            if (ActiveBrowser != null)
            {
                Console.WriteLine("Clearing IE cookie");
                IE ie = (IE)ActiveBrowser;
                ie.ClearCookies();
            }

        }

        public void ClearSpecificIECookie(string url)
        {

            if (ActiveBrowser != null)
            {
                Console.WriteLine("Clearing Specific IE cookie");
                IE ie = (IE)ActiveBrowser;
                ie.ClearCookies(url);
            }

        }

        public void ClearIECache()
        {

            if (ActiveBrowser != null)
            {
                Console.WriteLine("Clearing IE cache");
                IE ie = (IE)ActiveBrowser;
                ie.ClearCache();
            }
        }

        public void Maximize()
        {
            ActiveBrowser.ShowWindow(WatiN.Core.Native.Windows.NativeMethods.WindowShowStyle.Maximize);

        }

        public void Minimize()
        {
            ActiveBrowser.ShowWindow(WatiN.Core.Native.Windows.NativeMethods.WindowShowStyle.Minimize);

        }

        public void Refresh()
        {
            ActiveBrowser.Refresh();
        }

        public void GoBack()
        {
            ActiveBrowser.Back();
        }

        public void GoForward()
        {
            ActiveBrowser.Forward();
        }

        public string Html
        {
            get
            {
                return ActiveBrowser.Html;
                
            }
        }

        public string URL
        {
            get
            {
                return ActiveBrowser.Url;
            }
        }

        public string PageTitle
        {
            get
            {
                return ActiveBrowser.Title;
            }
        }

        public string GetCookieValue(string cookieName)
        {
            if (ActiveBrowser != null)
            {
                IE ie = (IE)ActiveBrowser;
                return ie.GetCookie(ActiveBrowser.Url, cookieName);
            }
            return "";
        }

        public void CaptureWebPage(string fileName)
        {
            if (ActiveBrowser != null)
            {
                IE ie = (IE)ActiveBrowser;
                ie.CaptureWebPageToFile(fileName);
            }
        }

        public static void CaptureEntireWebPage(string fileNamePrefix)
        {
            var ie = WatiN.Core.Browser.AttachToNoWait<IE>(WatiN.Core.Find.ByUrl(ActiveBrowser.Url), 10);
            ie.CaptureWebPageToFile(fileNamePrefix + ".png");
        }

        public void Close()
        {
            Console.WriteLine("Closing the ActiveBrowser");
            ActiveBrowser.Close();
        }

        public Link GetLinkByText(string linkText)
        {
            try
            {
                return ActiveBrowser.Link(Find.ByText(linkText));
            }
            catch (Exception)
            {
                return null;
            }
        }

        public List<Div> GetDivCollectionById(string divId)
        {
            try
            {
                var divs = BrowserDriver.ActiveBrowser.Divs;
                var myDivs = new List<Div>();
                foreach (var div in divs)
                {
                    if (div.Id == divId)
                        myDivs.Add(div);
                }

                return myDivs;
            }
            catch (Exception)
            {
                return null;
            }
        }

        public void ScrollToTop()
        {
            ActiveBrowser.RunScript("window.scrollTo(0,0)");
        }

        public void ScrollToBottom()
        {
            ActiveBrowser.RunScript("window.scrollTo(0,document['body'].offsetHeight)");
        }
        
    }
}
